Constraints
are data validation rules that are bound to a column or a set of
columns in a table. Constraints can also be used to enforce a
relationship between two entities represented as two tables. The
available types of constraints are as follows:
CHECK constraints
These constraints validate the integrity of data in a column by
checking it against a valid comparison. For example, you can use a CHECKBirth Date earlier than 01/01/1880. You can also use a CHECK constraint to validate that an e-mail address is always at least seven characters long. constraint to ensure that no one in your Employees table has a Primary Key constraints PRIMARY KEY
constraints represent the unique identifier column that will enforce
the uniqueness of each row. For example, you can designate the
CustomerID column as the PRIMARY KEY
for the Customers table. If you get two customers that have the same
values in the Name column and other columns, but represent different
people, you will use the PRIMARY KEY to distinguish between them. It is
a best practice to always have a PRIMARY KEY in each table and to use
surrogate PRIMARY KEYs that have no meaning to the application. Unique constraints These constraints are similar to PRIMARY KEY
constraints, except that you can have more than one unique constraint
per table. For example, you can designate that the combination of
FirstName, LastName, and TelephoneNumber is unique in the Customers
table and that the EMailAddress column can only contain unique values. FOREIGN KEY constraints These constraints enforce a relationship between two tables. For example, you can use a FOREIGN KEY
constraint to specify that any row in the Orders table must have a
corresponding row in the Customers table and that the tables are linked
through the CustomerID column, which is included in both tables. Once
this FOREIGN KEY constraint is enforced, you cannot delete a row from the Customers table that has related rows in the Orders table. Default constraints Also known as “defaults,” the DEFAULT
constraints specify a default value to be inserted into a column if no
value is inserted. Defaults can be bound to a column that is defined as
NULL or NOT NULL.
An example of a default is to use the value “Not Applicable” for the
ProductColor every time someone adds a product to the Products table
without specifying a color.
When
you attempt to insert, delete, or modify data in a table that will
result in a constraint violation, the statement will roll back. DML statements, like INSERT, UPDATE, DELETE, or MERGE, always succeed or fail as a whole. For example, if you were inserting 1,000 records into a table, but one violated a PRIMARY KEY or UNIQUE constraint, all 1,000 rows would roll back and nothing would be inserted. If a DELETE statement violated a FOREIGN KEY constraint, even on one row, the entire DELETE statement would fail and nothing would be deleted. You will never receive a partial result set from a DML statement. Example 1 shows the syntax used for working with constraints.
Tip
Remember that DML statements commit as a whole or not at all. A constraint violation will cause the entire statement to fail and roll back.
Example 1. Working with Constraints
CREATE TABLE Stars (StarID int PRIMARY KEY, StarName varchar(50) Unique, SolarMass decimal(10,2) CHECK(SolarMass > 0), StarType varchar(50) DEFAULT 'Orange Giant'); GO INSERT Stars (StarID, StarName, SolarMass) VALUES (1, 'Pollux', 1.86); INSERT Stars (StarID, StarName, SolarMass, StarType) VALUES (2, 'Sun', 1, 'Yellow dwarf'); SELECT * FROM Stars -- Results: -- StarID StarName SolarMass StarType -- ----------- ---------- ---------- ---------- -- 1 Pollux 1.86 Orange Giant -- 2 Sun 1.00 Yellow dwarf INSERT Stars (StarID, StarName, SolarMass, StarType) VALUES (2, 'Deneb', 6, 'White supergiant'); -- Results: -- Msg 2627, Level 14, State 1, Line 1 -- Violation of PRIMARY KEY constraint 'PK__Stars__06ABC647542C7691'. Cannot insert duplicate key in object 'dbo.Stars'. -- The statement has been terminated. INSERT Stars (StarID, StarName, SolarMass, StarType) VALUES (3, 'Deneb', -6, 'White supergiant'); -- Results: -- Msg 547, Level 16, State 0, Line 1 -- The INSERT statement conflicted with the CHECK constraint "CK__Stars__ SolarMass__58F12BAE". The conflict occurred in database "AdventureWorks", table "dbo.Stars", column 'SolarMass'. -- The statement has been terminated.
INSERT Stars (StarID, StarName, SolarMass, StarType) VALUES (3, 'Deneb', 6, 'White supergiant'); SELECT * FROM Stars -- Results: --DROP TABLE Stars -- StarID StarName SolarMass StarType -- ----------- ---------- ---------- ---------- -- 1 Pollux 1.86 Orange Giant -- 2 Sun 1.00 Yellow dwarf -- 3 Deneb 6.00 White supergiant
|
Enforcing Referential Integrity through FOREIGN KEY Constraints
A FOREIGN KEY
constraint creates a relationship between two tables, based on a value
held in a column or multiple columns. One of the tables participating
in the relationship contains a PRIMARY KEY used in the relationship.
The value of the primary key column can only appear once in this table.
You can also use a UNIQUE constraint instead of a PRIMARY KEY
constraint to define a relationship. Sometimes the table holding the
PRIMARY KEY is referred to as the parent table or the “one” in a
one-to-many relationship. The second table also has a column that
contains the same values as the PRIMARY KEY column in the parent table.
In the second table these values can repeat many times. This table is
referred to as the child table, or the “many” table in a one-to-many
relationship.
Consider
this simple example. The Customers table may contain columns
CustomerID, CompanyName, and StreetAddress. The CustomerID column is
the PRIMARY KEY column and contains unique values. The Orders table
contains an OrderID column, a CustomerID column, and an OrderAmount
column. The CustomerID column in the Orders table contains the unique
identity of the customer who has placed the order. To look up which
customer an order belongs to, look them up by their CustomerID. To find
all orders for a particular customer, look them up by their CustomerID.
The CustomerID column in the Orders table is known as a FOREIGN KEY because it is a key of a foreign entity, an entity that does not belong in the table.
By creating a FOREIGN KEY
constraint between two tables, their relationship is formalized. The
rules of the constraint are applied to the relationship. By default,
you cannot delete a parent record, if there are related child records
in the child table referenced by a FOREIGN KEY constraint. You can also explicitly specify an action to take when the parent record is deleted or the key value of the parent record is updated. To do this, use the ON UPDATE and ON DELETE optional clauses when creating a FOREIGN KEY constraint. The following actions are available:
NO ACTION This is the default action. No special action is taken, and if the FOREIGN KEY is violated, the statement rolls back. CASCADE
Propagate the update or delete action to child rows. If you delete a
parent row that participates in a cascading relationship, all child
rows will be deleted. If you change a key value of a parent row, the
corresponding child rows will also change. SET NULL Set the values of the FOREIGN KEY column to null for all related records. SET DEFAULT Set the values of the FOREIGN KEY column to its default values for all related records.
Columns
marked as FOREIGN KEYs can contain null values. However, this practice
is not recommended because when a FOREIGN KEY consists of two or more
columns and contains null values, the constraint cannot be verified,
and the integrity of your data cannot be guaranteed.
It is also possible for a FOREIGN KEY constraint to reference columns in the same table. This is known as a self-reference, and when querying a table in this arrangement it is referred to as a self-join.
An example of a self-reference is a Generations table containing names
of people with the columns PersonID, PersonName, and MotherID. The
mother is also a person stored in the Generations table, and therefore,
you can create a FOREIGN KEY relationship from the MotherID (FOREIGN
KEY column) referencing PersonID (PRIMARY KEY column).
|
FOREIGN KEY
constraints are frequently used by queries to join the parent and child
tables. For this reason, it is recommended that you create a
nonclustered index on every FOREIGN KEY contained in a table.
Example 2 creates two tables and links them by a FOREIGN KEY constraint.
Example 2. Working with FOREIGN KEY Constraints
CREATE TABLE Team( TeamID int PRIMARY KEY, TeamName varchar(50)); GO CREATE TABLE TeamMember( TeamMemberID int PRIMARY KEY, FullName varchar(100), TeamID int CONSTRAINT FK_Team_TeamMember FOREIGN KEY REFERENCES dbo.Team(TeamID)); GO INSERT Team VALUES (1, 'Development'), (2, 'Testing'), (3, 'Management'); INSERT TeamMember VALUES (1, 'Valentine', 1), (2, 'Bryant', 1), (3, 'Shane', 1), (4, 'Keith', 3) SELECT Team.TeamID, TeamName, FullName FROM Team LEFT JOIN TeamMember ON Team.TeamID = TeamMember.TeamID ; GO -- Results: -- TeamID TeamName FullName -- ----------- ----------- ----------- -- 1 Development Valentine -- 1 Development Bryant -- 1 Development Shane -- 2 Testing NULL -- 3 Management Keith DELETE FROM Team WHERE TeamID = 2; GO -- Results: -- (1 row(s) affected) DELETE FROM Team WHERE TeamID = 3; GO -- Results: -- Msg 547, Level 16, State 0, Line 1
-- The DELETE statement conflicted with the REFERENCE constraint "FK_Team_ TeamMember". The conflict occurred in database "AdventureWorks", table "dbo. TeamMember", column 'TeamID'. -- The statement has been terminated. ALTER TABLE TeamMember DROP CONSTRAINT FK_Team_TeamMember; GO ALTER TABLE TeamMember ADD CONSTRAINT FK_Team_TeamMember FOREIGN KEY(TeamID) REFERENCES dbo.Team(TeamID) ON DELETE CASCADE; GO DELETE FROM Team WHERE TeamID = 3; GO -- Results: -- (1 row(s) affected) DROP TABLE TeamMember; GO DROP TABLE Team; GO
|
When you add FOREIGN KEY or CHECK
constraints to an existing table that already contains data, by default
all data in the table is validated against the constraint. Depending on
the amount of data in your table, this may take a long time. If you
wish to instruct SQL Server not to validate data integrity, and just
create the constraint, you can specify WITH NOCHECK.
The constraint will apply to new and modified rows, but the existing
rows will not be examined. Data integrity is not checked when
reenabling a previously disabled constraint.
It is not recommended that you specify WITH NOCHECK
as this may result in erratic behavior when updating existing data. For
example, you may be updating a column that has nothing to do with the
constraint, and you may receive constraint violation errors. Only use WITH NOCHECK in situations that explicitly require it.
You must understand that constraints that were defined WITH NOCHECK
are not used by the query optimizer to create efficient queries. To
allow the query optimizer to use these constraints, you must reenable
them using the ALTER TABLE statement with the CHECK CONSTRAINT ALL clause.
|
|